//
//  UITextView+Placeholder.m
//  GLGW_Shoping
//
//  Created by yang on 2018/11/28.
//  Copyright © 2018年 yang. All rights reserved.
//

#import "UITextView+Placeholder.h"
#import <objc/runtime.h>
#import "CYEmoticon.h"
#import "CYTextAttachment.h"
static const char placeholderKey = '\3';
static const char placeholderColorKey = '\4';
static const char placeholderLabelKey = '\5';
static const char maxInputLengthKey = '\6';
static const char textEdgeInset = '\7';

static UILabel *placeholderLabel;

@implementation UITextView (Placeholder)
+ (void)load{
    Method dealloc = class_getInstanceMethod(self, NSSelectorFromString(@"dealloc"));
    Method ccc_dealloc = class_getInstanceMethod(self, @selector(ccc_dealloc));
    method_exchangeImplementations(dealloc, ccc_dealloc);
    
    Method initWithFrame = class_getInstanceMethod(self, NSSelectorFromString(@"initWithFrame:"));
    Method ccc_initWithFrame = class_getInstanceMethod(self, @selector(ccc_initWithFrame:));
    method_exchangeImplementations(initWithFrame, ccc_initWithFrame);
    
    Method drawRect = class_getInstanceMethod(self, NSSelectorFromString(@"drawRect:"));
    Method ccc_drawRect = class_getInstanceMethod(self, @selector(ccc_drawRect:));
    method_exchangeImplementations(drawRect, ccc_drawRect);
    
    Method setText = class_getInstanceMethod(self, NSSelectorFromString(@"setText:"));
    Method ccc_setText = class_getInstanceMethod(self, @selector(ccc_setText:));
    method_exchangeImplementations(setText, ccc_setText);
    
    Method setFont = class_getInstanceMethod(self, NSSelectorFromString(@"setFont:"));
    Method ccc_setFont = class_getInstanceMethod(self, @selector(ccc_setFont:));
    method_exchangeImplementations(setFont, ccc_setFont);
    
    Method setAttributedText = class_getInstanceMethod(self, NSSelectorFromString(@"setAttributedText:"));
    Method ccc_setAttributedText = class_getInstanceMethod(self, @selector(ccc_setAttributedText:));
    method_exchangeImplementations(setAttributedText, ccc_setAttributedText);
}
- (void)drawRect:(CGRect)rect{
    
}
- (void)ccc_drawRect:(CGRect)rect{
 
    if (self.hasText) {
        return;
    }
    /**
     placeholder文字的绘制情况跟自身的text 属性相关，
     所以要重写set方法去调用drawRect方法（setNeedsDisplay）
     **/
//    DLog(@"==%.2f",self.newTextContainerInset.top);
    if (self.newTextContainerInset.top > 0) {
        rect.origin.x = self.newTextContainerInset.left + kWidthProportion_In_iPhoneTriploid(5);
        rect.origin.y = self.newTextContainerInset.top;
        self.textContainerInset = self.newTextContainerInset;
    } else {
        rect.origin.x = 5;
        rect.origin.y = 8;
    }
    rect.size.width -= 2 * rect.origin.x;
    [self.placeholder drawInRect:rect withAttributes:self.placeholderAttributes];
}

- (void)setNewTextContainerInset:(UIEdgeInsets)newTextContainerInset
{
    NSString *topStr = [NSString stringWithFormat:@"%.2f",newTextContainerInset.top];
    NSString *leftStr = [NSString stringWithFormat:@"%.2f",newTextContainerInset.left];
    NSString *bottomStr = [NSString stringWithFormat:@"%.2f",newTextContainerInset.bottom];
    NSString *rightStr = [NSString stringWithFormat:@"%.2f",newTextContainerInset.right];
    NSArray *arr = @[topStr,leftStr,bottomStr,rightStr];
    objc_setAssociatedObject(self, &textEdgeInset, arr, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIEdgeInsets)newTextContainerInset
{
    NSArray *arr = objc_getAssociatedObject(self, &textEdgeInset);
    UIEdgeInsets newEdg;
    if (arr.count >= 4) {
        newEdg = UIEdgeInsetsMake([arr[0] floatValue], [arr[1] floatValue], [arr[2] floatValue], [arr[3] floatValue]);
    } else {
        newEdg = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    return newEdg;
}

- (instancetype)ccc_initWithFrame:(CGRect)frame{
    [self ccc_initWithFrame:frame];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ccc_textViewDidChangeNotification:) name:UITextViewTextDidChangeNotification object:nil];
    return self;
}
- (void)ccc_dealloc{
    if (self==[UITextView class]) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil];
        
    }
}
- (void)setPlacehoderLabel:(UILabel *)placehoderLabel{
    objc_setAssociatedObject(self, &placeholderLabelKey, placehoderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}
- (void)setPlaceholder:(NSString *)placeholder{
    
    objc_setAssociatedObject(self, &placeholderKey, placeholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self setNeedsDisplay];
}
- (void)setPlaceholderAttributes:(NSDictionary *)placeholderAttributes{
    objc_setAssociatedObject(self, &placeholderColorKey, placeholderAttributes, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self setNeedsDisplay];
}
- (void)setMaxInputLength:(NSInteger)maxInputLength{
    objc_setAssociatedObject(self, &maxInputLengthKey, @(maxInputLength), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)maxInputLength{
    NSNumber *inputNumber = objc_getAssociatedObject(self, &maxInputLengthKey);
    return inputNumber.integerValue;
}
- (NSString *)placeholder{
    return objc_getAssociatedObject(self, &placeholderKey);
}
- (NSDictionary *)placeholderAttributes{
    return objc_getAssociatedObject(self, &placeholderColorKey);
}
- (UILabel *)placehoderLabel{
    return objc_getAssociatedObject(self, &placeholderLabelKey);
}
- (void)ccc_setText:(NSString *)text{
    [self ccc_setText:text];
    [self setNeedsDisplay];
}
- (void)ccc_setAttributedText:(NSAttributedString *)attributedText{
    [self ccc_setAttributedText:attributedText];
    [self setNeedsDisplay];
}
- (void)ccc_setFont:(UIFont *)font{
    [self ccc_setFont:font];
    [self setNeedsDisplay];
}
- (void)ccc_textViewDidChangeNotification:(NSNotification *)notification{
    [self setNeedsDisplay];
    if (self.maxInputLength<=0) {
        return;
    }
    NSString *InputMethodType = [[UIApplication sharedApplication]textInputMode].primaryLanguage;
    
    // 如果当前输入法为汉语输入法
    if ([InputMethodType isEqualToString:@"zh-Hans"]) {
        
        // 获取选中部分
        UITextRange *selectedRange = [self markedTextRange];
        
        //获取选中部分的偏移量, 此部分为用户未决定输入部分
        UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
        
        // 当没有标记部分时截取字符串
        if (position == nil) {
            self.text = [self textViewCurrentText];
        }
    }else {
        self.text = [self textViewCurrentText];
    }
}
- (NSString *)textViewCurrentText{
    return self.text.length>self.maxInputLength?[self.text substringToIndex:self.maxInputLength]:self.text;
}


///插入表情的方法
- (void)insertEmoticon:(CYEmoticonCell *)cell
{
    //取出数据模型
    CYEmoticon *emoticon = cell.emoticon;
    //执行插入表情方法
    [self textViewInsertEmoticon:emoticon];
}

///插入表情的具体操作
- (void)textViewInsertEmoticon:(CYEmoticon *)emoticon
{
    //如果是空按钮
    if (emoticon.isEmpty) {
        DLog(@"空");
        return;
    }
    //如果是删除按钮
    if (emoticon.isDelete) {
        //删除
        [self deleteText];
        return;
    }
    //如果是表情
    if (emoticon.png) {
        //插入表情
        [self insertImage:emoticon];
        return;
    }
}

///删除文本
- (void)deleteText
{
    [self deleteBackward];
}

///插入图片
- (void)insertImage:(CYEmoticon *)emoticon
{
    //设置字体
    UIFont *font = SYSTEMFONT(15);
    if (self.font) {
        font = self.font;
    }
    //创建自定义附件
    CYTextAttachment *textAtta = [[CYTextAttachment alloc] init];
    //设置照片
    textAtta.image = [UIImage imageNamed:emoticon.png];
    //插入同时，在自定义附件中 记录str
    textAtta.str = emoticon.str;
    //设置附件的大小
    textAtta.bounds = CGRectMake(0, -4,font.lineHeight,font.lineHeight);
    //将附件转成NSAttributedString
    NSAttributedString *attri = [NSAttributedString attributedStringWithAttachment:textAtta];
    //建text的文本转化为可变属性文本
    NSMutableAttributedString *attStrM = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
    //获得目前光标的位置
    NSRange selectedRange = self.selectedRange;
    //插入文字
    [attStrM insertAttributedString:attri atIndex:selectedRange.location];
    //设置可变文本的属性
    [attStrM addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attStrM.length)];
    //再次记住光标位置
    NSRange newSelectedRange = NSMakeRange(selectedRange.location+1, 0);
    //重新给文本赋值
    self.attributedText = attStrM;
    //恢复光标的位置（上面一句代码执行之后，光标会移到最后面）
    self.selectedRange = newSelectedRange;
}

///将textView中的图片转成字符
- (NSString *)fullText
{   //获得属性文本
    NSAttributedString *attriText = self.attributedText;
    //定义一个字符串用于接收转换的字符
    __block NSString *strM = @"";
    //遍历属性文本
    [attriText enumerateAttributesInRange:NSMakeRange(0, attriText.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired  usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
        //取得附件
        CYTextAttachment *attachment = attrs[@"NSAttachment"];
        if (attachment) {
            //是表情
            strM = [strM stringByAppendingString:attachment.str];
        }else{
            //是文字
            NSString *str = [attriText.string substringWithRange:range];
            //拼接
            strM = [strM stringByAppendingString:str];
        }
    }];
    return strM;
}

+ (NSString *)fullTextWithAttriStr:(NSAttributedString *)attriStr
{
    //定义一个字符串用于接收转换的字符
    __block NSString *strM = @"";
    //遍历属性文本
    [attriStr enumerateAttributesInRange:NSMakeRange(0, attriStr.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired  usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
        //取得附件
        CYTextAttachment *attachment = attrs[@"NSAttachment"];
        if (attachment) {
            //是表情
            strM = [strM stringByAppendingString:attachment.str];
        }else{
            //是文字
            NSString *str = [attriStr.string substringWithRange:range];
            //拼接
            strM = [strM stringByAppendingString:str];
        }
    }];
    return strM;
}
@end
